import json
import time
import requests
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import pandas as pd
import random
import jieba

from pyecharts.charts import Line, Bar, Pie, Map
from pyecharts import options as opts

headers = {
        'Host': 'music.163.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}


def get_comments(page):
    """
        获取评论信息
    """
    url = 'https://music.163.com/api/v1/resource/comments/R_SO_4_2004684052?limit=20&offset=' + str(page)
    response = requests.get(url=url, headers=headers)
    # 将字符串转为json格式
    result = json.loads(response.text)
    items = result['comments']
    for item in items:
        # 用户名
        user_name = item['user']['nickname'].replace(',', '，')
        # 用户ID
        user_id = str(item['user']['userId'])
        # 获取用户信息
        user_message = get_user(user_id)
        # 用户年龄
        user_age = str(user_message['age'])
        # 用户性别
        user_gender = str(user_message['gender'])
        # 用户所在地区
        user_city = str(user_message['city'])
        # 个人介绍
        user_introduce = user_message['sign'].strip().replace('\n', '').replace(',', '，')
        # 评论内容
        comment = item['content'].strip().replace('\n', '').replace(',', '，')
        # 评论ID
        comment_id = str(item['commentId'])
        # 评论点赞数
        praise = str(item['likedCount'])
        # 评论时间
        date = time.localtime(int(str(item['time'])[:10]))
        date = time.strftime("%Y-%m-%d %H:%M:%S", date)
        print(user_name, user_id, user_age, user_gender, user_city, user_introduce, comment, comment_id, praise, date)

        with open('music_comments.csv', 'a', encoding='utf-8-sig') as f:
            f.write(user_name + ',' + user_id + ',' + user_age + ',' + user_gender + ',' + user_city + ',' + user_introduce + ',' + comment + ',' + comment_id + ',' + praise + ',' + date + '\n')
        f.close()


def get_user(user_id):
    """
    获取用户注册时间
    """
    data = {}
    url = 'https://music.163.com/api/v1/user/detail/' + str(user_id)
    # 使用2808proxy代理
    response = requests.get(url=url, headers=headers)
    # 将字符串转为json格式
    js = json.loads(response.text)
    if js['code'] == 200:
        # 性别
        data['gender'] = js['profile']['gender']
        # 年龄
        if int(js['profile']['birthday']) < 0:
            data['age'] = 0
        else:
            data['age'] = (2018 - 1970) - (int(js['profile']['birthday']) // (1000 * 365 * 24 * 3600))
        if int(data['age']) < 0:
            data['age'] = 0
        # 城市
        data['city'] = js['profile']['city']
        # 个人介绍
        data['sign'] = js['profile']['signature']
    else:
        data['gender'] = '无'
        data['age'] = '无'
        data['city'] = '无'
        data['sign'] = '无'
    return data


def main():
    for i in range(0, 40, 20):
        print('\n---------------第 ' + str(i // 20 + 1) + ' 页---------------')
        get_comments(i)


if __name__ == '__main__':
    main()



# 读取数据
df = pd.read_csv('music_comments.csv', header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# 根据评论ID去重
df = df.drop_duplicates('commentid')
# 分组汇总
user_message = df.groupby(['userid'])
user_com = user_message['userid'].agg(['count'])
user_com.reset_index(inplace=True)
user_com_last = user_com.sort_values('count', ascending=False)[0:10]
print(user_com_last)



# 读取数据
df = pd.read_csv('music_comments.csv',low_memory=False, header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# 根据评论ID去重
df = df.drop_duplicates('commentid')
# 获取评论日期
df['time'] = pd.to_datetime([str(i).split(' ')[0] for i in df['date']])

# 分组汇总
date_message = df.groupby(['time'])
date_com = date_message['time'].agg(['count'])
date_com.reset_index(inplace=True)

# 绘制走势图
attr = date_com['time']
v1 = date_com['count']
line = Line("歌曲发布后评论的日期分布", title_pos='center', title_top='22', width=1000, height=600)
line.add("", attr, v1, is_smooth=True, is_fill=True, area_color="#000", is_xaxislabel_align=True, xaxis_min="dataMin", area_opacity=0.3, mark_point=["max"], mark_point_symbol="pin", mark_point_symbolsize=55)
line.render("热门歌曲评论的日期分布.html")



# 设置文本随机颜色
def random_color_func(word=None, font_size=None, position=None, orientation=None, font_path=None, random_state=None):
    h, s, l = random.choice([(188, 72, 53), (253, 63, 56), (12, 78, 69)])
    return "hsl({}, {}%, {}%)".format(h, s, l)


# 读取信息
df = pd.read_csv('music_comments.csv', header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# 根据评论ID去重
df = df.drop_duplicates('commentid')
words = pd.read_csv('stop_words.csv', encoding='utf-8', sep='\t', names=['stopword'])
# 分词
text = ''
for line in df['comment']:
    text += ' '.join(jieba.cut(str(line), cut_all=False))
# 停用词
stopwords = set('')
stopwords.update(words['stopword'])
backgroud_Image = plt.imread('music.jpg')

wc = WordCloud(
    background_color='white',
    mask=backgroud_Image,
    font_path='C:/Windows/Fonts/STCAIYUN.TTF',
    max_words=2000,
    max_font_size=250,
    min_font_size=15,
    color_func=random_color_func,
    prefer_horizontal=1,
    random_state=50,
    stopwords=stopwords
)

wc.generate_from_text(text)
# 看看词频高的有哪些
process_word = WordCloud.process_text(wc, text)
sort = sorted(process_word.items(), key=lambda e: e[1], reverse=True)
print(sort[:50])
plt.imshow(wc)
plt.axis('off')
wc.to_file("网易云音乐评论词云.jpg")
print('生成词云成功!')

# # 读取数据
# df = pd.read_csv('music_comments.csv',low_memory=False, header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# # 根据评论ID去重
# df = df.drop_duplicates('commentid')
# # 去除无年龄信息的
# df = df[df.age != 'null']
#
# # 分组汇总
# age_message = df.groupby(['age'])
# age_com = age_message['age'].agg(['count'])
# age_com.reset_index(inplace=True)
#
# # 生成柱状图
# attr = age_com['age']
# v1 = age_com['count']
# bar = Bar("热门歌曲评论用户的年龄分布", title_pos='center', title_top='18', width=800, height=1000)
# bar.add("", attr, v1, is_stack=True, is_label_show=False)
# bar.render("热门歌曲评论用户的年龄分布.html")




# 读取数据
df = pd.read_csv('music_comments.csv', low_memory=False, header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# 根据评论ID去重
df = df.drop_duplicates('commentid')

# 将年龄列转换为数值，无效值设为 NaN
df['age'] = pd.to_numeric(df['age'], errors='coerce')

# 去除缺失的年龄信息
df = df.dropna(subset=['age'])

# 定义年龄段分组函数
def age_group(age):
    if age >= 0 and age < 10:
        return '0~9'
    elif age >= 10 and age < 20:
        return '10~19'
    elif age >= 20 and age < 30:
        return '20~29'
    elif age >= 30 and age < 40:
        return '30~39'
    elif age >= 40 and age < 50:
        return '40~49'
    elif age >= 50 and age < 60:
        return '50~59'
    elif age >= 60 and age < 70:
        return '60~69'
    elif age >= 70 and age < 80:
        return '70~79'
    else:
        return '80+'

# 对年龄进行分组
df['age_group'] = df['age'].apply(age_group)

# 分组汇总
age_message = df.groupby(['age_group'])
age_com = age_message.size()  # 统计每个年龄段的评论数
age_com = age_com.reset_index(name='count')

# 生成柱状图
attr = age_com['age_group'].tolist()
v1 = age_com['count'].tolist()
bar = Bar("热门歌曲评论用户的年龄分布", title_pos='center', title_top='18', width=800, height=600)
bar.add("", attr, v1, is_stack=True, is_label_show=False)
bar.render("热门歌曲评论用户的年龄分布.html")





# def city_group(cityCode):
#     """
#     城市编码
#     """
#     city_map = {
#         '11': '北京',
#         '12': '天津',
#         '31': '上海',
#         '50': '重庆',
#         '5e': '重庆',
#         '81': '香港',
#         '82': '澳门',
#         '13': '河北',
#         '14': '山西',
#         '15': '内蒙古',
#         '21': '辽宁',
#         '22': '吉林',
#         '23': '黑龙江',
#         '32': '江苏',
#         '33': '浙江',
#         '34': '安徽',
#         '35': '福建',
#         '36': '江西',
#         '37': '山东',
#         '41': '河南',
#         '42': '湖北',
#         '43': '湖南',
#         '44': '广东',
#         '45': '广西',
#         '46': '海南',
#         '51': '四川',
#         '52': '贵州',
#         '53': '云南',
#         '54': '西藏',
#         '61': '陕西',
#         '62': '甘肃',
#         '63': '青海',
#         '64': '宁夏',
#         '65': '新疆',
#         '71': '台湾',
#         '10': '其他',
#     }
#     cityCode = str(cityCode)
#     return city_map[cityCode[:2]]
def city_group(cityCode):
    city_map = {
        '11': '北京',
        '12': '天津',
        '31': '上海',
        '50': '重庆',
        '5e': '重庆',
        '81': '香港',
        '82': '澳门',
        '13': '河北',
        '14': '山西',
        '15': '内蒙古',
        '21': '辽宁',
        '22': '吉林',
        '23': '黑龙江',
        '32': '江苏',
        '33': '浙江',
        '34': '安徽',
        '35': '福建',
        '36': '江西',
        '37': '山东',
        '41': '河南',
        '42': '湖北',
        '43': '湖南',
        '44': '广东',
        '45': '广西',
        '46': '海南',
        '51': '四川',
        '52': '贵州',
        '53': '云南',
        '54': '西藏',
        '61': '陕西',
        '62': '甘肃',
        '63': '青海',
        '64': '宁夏',
        '65': '新疆',
        '71': '台湾',
        '10': '其他',
    }
    cityCode = str(cityCode)
    return city_map.get(cityCode[:2], '未知')  # 如果找不到对应城市代码，返回 '未知'

# # 在你的代码中应用 city_group 函数
# df['location'] = df['city'].apply(city_group)

# 读取数据
df = pd.read_csv('music_comments.csv',low_memory=False, header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# 根据评论ID去重
df = df.drop_duplicates('commentid')
# 进行省份匹配
df['location'] = df['city'].apply(city_group)

# 分组汇总
loc_message = df.groupby(['location'])
loc_com = loc_message['location'].agg(['count'])
loc_com.reset_index(inplace=True)

# 绘制地图
value = [i for i in loc_com['count']]
attr = [i for i in loc_com['location']]
map = Map("热门歌曲评论用户的地区分布图", title_pos='center', title_top=0)
map.add("", attr, value, maptype="china", is_visualmap=True, visual_text_color="#000", is_map_symbol_show=False, visual_range=[0, 600])
map.render('热门歌曲评论用户的地区分布图.html')


# # 读取数据
# df = pd.read_csv('music_comments.csv',low_memory=False, header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# # 根据评论ID去重
# df = df.drop_duplicates('commentid')
# # 去除无性别信息的
# df = df[df.gender != 0]
# df = df[df.gender != 3]
#
# # 分组汇总
# gender_message = df.groupby(['gender'])
# gender_com = gender_message['gender'].agg(['count'])
# gender_com.reset_index(inplace=True)
#
# # 生成饼图
# attr = ['男', '女']
# v1 = gender_com['count']
# pie = Pie("热门歌曲评论用户的性别情况", title_pos='center', title_top=0)
# pie.add("", attr, v1, radius=[40, 75], label_text_color=None, is_label_show=True, legend_orient="vertical", legend_pos="left", legend_top="%10")
# pie.render("热门歌曲评论用户的性别情况.html")
# 读取数据
df = pd.read_csv('music_comments.csv', low_memory=False, header=None, names=['name', 'userid', 'age', 'gender', 'city', 'text', 'comment', 'commentid', 'praise', 'date'], encoding='utf-8-sig')
# 根据评论ID去重
df = df.drop_duplicates('commentid')
# 过滤掉性别代码为无和0的数据
df = df[(df['gender'] != '无') & (df['gender'] != 0)]

# 分组汇总
gender_message = df.groupby(['gender'])
gender_com = gender_message.size()  # 统计每个性别的评论数
gender_com = gender_com.rename({1: '男', 2: '女'})  # 将性别代码转换为文字描述
gender_com = gender_com.reset_index(name='count')

# 生成饼图
attr = gender_com['gender'].tolist()
v1 = gender_com['count'].tolist()
pie = Pie("热门歌曲评论用户的性别情况", title_pos='center', title_top=0)
pie.add("", attr, v1, radius=[40, 75], label_text_color=None, is_label_show=True, legend_orient="vertical", legend_pos="left", legend_top="%10")
pie.render("热门歌曲评论用户的性别情况.html")